﻿using System;
using System.Text;

namespace MyFastDataSourceBind
{
    /// <summary>
    /// 可绑定数据源的记录定位列表控件，该控件用于快速定位记录
    /// </summary>
    /// <remarks>编制 袁永福</remarks>
    public class XDBKeyListBox : System.Windows.Forms.ListBox, IXDataSourceable
    {
        /// <summary>
        /// 初始化对象
        /// </summary>
        public XDBKeyListBox()
        {
        }

        private string strXDataFieldName = null;
        /// <summary>
        /// 绑定的数据源字段名
        /// </summary>
        [System.ComponentModel.Editor(
            typeof(XDataFieldNameEditor),
            typeof(System.Drawing.Design.UITypeEditor))]
        public string XDataFieldName
        {
            get { return strXDataFieldName; }
            set { strXDataFieldName = value; }
        }

        private string strXDataSourceName = null;
        /// <summary>
        /// 按钮操作的数据源名称
        /// </summary>
        [System.ComponentModel.Editor(
            typeof(XDataSourceNameEditor),
            typeof(System.Drawing.Design.UITypeEditor))]
        public string XDataSourceName
        {
            get
            {
                return strXDataSourceName;
            }
            set
            {
                strXDataSourceName = value;
                XDataSourceEventSender.Register(this, this.strXDataSourceName);
            }
        }


        /// <summary>
        /// 销毁对象，撤销数据源绑定
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            XDataSourceEventSender.UnRegister(this);
        }

        /// <summary>
        /// 锁定控件事件标志
        /// </summary>
        private bool bolLock = false;

        /// <summary>
        /// 保存的数据版本状态
        /// </summary>
        private int intDataTableVersion = 0;
        /// <summary>
        /// 处理数据源事件
        /// </summary>
        /// <param name="Sender">参数</param>
        /// <param name="Args">参数</param>
        public void HandleDataSourceEvent(object Sender, XDataSourceEventArgs Args)
        {
            this.Enabled = !Args.DataSource.Editing;
            switch (Args.Style)
            {
                case XDataSourceEventStyle.FillUI:
                    // 处理数据源FillUI事件，从数据源中获得数据并设置用户界面。
                    // 检查控件锁定状态，若控件锁定了则退出处理
                    // 这里的代码可能会触发控件的SelectedIndexChanged事件，而SelectedIndexChanged事件
                    // 会调用数据源的一些方法，导致数据源套嵌广播FillUI事件，如此形成递归，
                    // 而使用 bolLock 标识变量是为了避免这种递归。
                    if (bolLock == false)
                    {
                        bolLock = true;
                        // 开始更新数据
                        this.BeginUpdate();
                        if (intDataTableVersion != Args.DataSource.DataTableVersion)
                        {
                            // 若保存的数据版本号不等于数据源的数据版本号则将数据源中
                            // 所有记录的指定名称的字段值填充到列表中
                            intDataTableVersion = Args.DataSource.DataTableVersion;
                            this.Items.Clear();
                            object[] items = Args.DataSource.GetValues(this.XDataFieldName);
                            if (items != null && items.Length > 0)
                            {
                                this.Items.AddRange(items);
                            }
                        }
                        // 获得当前记录序号
                        int index = Args.DataSource.RowIndex;
                        if (index >= 0 && index < this.Items.Count)
                        {
                            // 设置列表框控件的序号
                            this.SelectedIndex = index;
                        }
                        this.EndUpdate();
                        bolLock = false;
                    }
                    break;
            }
        }

        /// <summary>
        /// 处理列表当前项目改变事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnSelectedIndexChanged(EventArgs e)
        {
            if (bolLock == false)
            {
                bolLock = true;
                // 获得指定名称的数据源对象
                XDataSource ds = XDataSource.GetInstance(this.XDataSourceName);
                if (ds != null && ds.Editing == false)
                {
                    if (this.SelectedIndex >= 0)
                    {
                        // 设置数据源的当前记录序号为列表框中当前项目的序号
                        ds.RowIndex = this.SelectedIndex;
                    }
                }
                bolLock = false;
            }
            base.OnSelectedIndexChanged(e);
        }

    }//public class XDBKeyListBox
}